/*
 *  This file is part of WWWPal.
 *
 *  Copyright (C) 2003  Dr. John Punin, Department of Computer Science
 *  Rensselaer Polytechnic Institute
 *
 *  WWWPal is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  WWWPal is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "client.h"
#include <rep_blinks.h>
#include "report_map.h"
#include "dirpartition.h"
#include <GR_write_html.h>

static int max_level;
static int max_leaves;

int
report_map_site(mainFrame *mf, tgrFrame *tgf, char *name_file, struct pt *r, 
		int list, int simple,int no_class_edges)
{
  FILE *fp;
  char *title=NULL;
  if(!name_file)
    {
      fprintf(stderr, "HTML File name for Map Site is missing\n");
      return -1;
    }
  fp = fopen(name_file, "w+");
  if(!fp)
    {
      fprintf(stderr, "Can't open %s \n",name_file);
      return -1;
    }
  max_level = 0;
  max_leaves = 0;
  title = title_from_root(tgf,r);
  write_head_html_file(fp,title);
  write_body_file_map(mf,tgf,fp,r, list,simple,no_class_edges);
  write_end_html_file(fp);
  fclose(fp);
  if(title) {
    free(title); title = NULL;
  }
  return 0;
}

char *
title_from_root(tgrFrame *tgf, struct pt *r)
{
  GraphFrame *gf = tgf->gf;
  struct pt *root = r;
  if(!root)
    root = get_last_vertex(gf);
  if(root)
    {
      const char *a1 = get_attribute(root,"title");
      int len = a1 ? strlen(a1):0;
      char *ti = malloc(len+ 20);
      if(!ti) {
	  fprintf(stderr,"Out of Memory title_from_root\n");
	  abort();
      }
      if(a1)
	sprintf(ti, "Site Map of %s", a1);
      else
	sprintf(ti, "Site Map");
      return ti;
    }
  else
    {
      char *ti = NULL;
      GRStrAllocCopy(ti,"Site Map");
      return ti;
    }
}
int
write_body_file_map(mainFrame *mf, tgrFrame *tgf,FILE *fp, struct pt *r, 
		    int list,int simple,int no_class_edges)
{
  GraphFrame *gf = tgf->gf;
  struct pt *root=r;
  const char *a1;
  time_t now;

  if(!root)
    root = get_last_vertex(gf);
  
  if(!root)
    return -1;

  a1=get_attribute(root,"title");

  printf("ROOT is %s\n", root->label);

  now = time(NULL);
  write_start_body_html_file(fp,"#ffffff");
  write_header_html_file(fp,1,"Site Map");
  if(a1)
      write_header_html_file(fp,2,a1);
  write_bold_html_file(fp,"Last Update :");
  fprintf(fp, " %s",ctime(&now));
  write_break_html_file(fp);

  /*fprintf(fp, "<BODY bgcolor=\"#ffffff\">\n");
  fprintf(fp,"<H1>Site Map</H1>\n");
  if(a1)
    fprintf(fp,"<H2>%s</H2>\n", a1);
    fprintf(fp," <B>Last Update :</B> %s<BR>\n",ctime(&now));*/

  if(!no_class_edges) /* Classification of Edges */
   {
     set_method_tree(gf, BFS_FV_TREE);
     compute_tree_graph(gf,root);
     set_method_tree(gf, BFS_TREE);
   }

  reset_mark_pick_vertices(gf);

  if(list)
    {
      visit_nodes_by_DFS(tgf,root,NULL,fp,simple);
      return 0;
    }

  /* USING TABLES */
  max_leaves = visit_nodes_by_DFS_table(tgf, root, NULL,fp, 0, 1,simple);

  if(max_level > 1)
    {
      reset_mark_pick_vertices(gf);
      write_start_table_html_file(fp, max_level);
      /*print_header_table(fp, max_level);*/
      visit_nodes_by_DFS_table(tgf, root, NULL,fp, 1, 1,simple);
      write_end_table_html_file(fp);
      /*print_footer_table(fp);*/
    }
  return 0;
}

void 
visit_nodes_by_DFS(tgrFrame *tgf, struct pt *v, PEDGE e, FILE *fp,int simple)
{
  LNode_type *poed;
  LNode_type *eout = get_edges_out(v);
  int flag =0;

  v->mark = True;

  if(simple)
    print_simple_node_info(fp,v);
  else
    print_node_info(fp,v,e);  

  for(poed = eout->next; poed != eout; poed = poed->next)
    {
      struct edge *e = (struct edge *)poed->info;
      struct pt * tv;

      if(e->attrib == 'z')
	continue;

      if(e->class != TREE_CLASS)
	continue;
      tv = get_to_vertex(e);
      flag++;
      if(flag==1)
	  write_start_ul_html_file(fp);
      /*fprintf(fp,"<UL>\n");*/
      if( tv->mark == False)
	{
	  write_item_html_file(fp);
	  /*fprintf(fp,"<LI>");*/
	  visit_nodes_by_DFS(tgf, tv, e,fp,simple);
	}
    }

  if(flag)
      write_end_ul_html_file(fp);
  /*fprintf(fp,"</UL>\n");*/

  v->pick = True;
}

int
visit_nodes_by_DFS_table(tgrFrame *tgf, struct pt *v, PEDGE e, FILE *fp, int what, int level,int simple)
{
  LNode_type *poed;
  LNode_type *eout = get_edges_out(v);
  static int flag_tr = 0;

  v->mark = True;
  v->level = level;

  if(!what)
    v->prelim = 0;

  if(what)
    {
      if(!flag_tr)
	{
	  write_start_tr_html_file(fp);
	  flag_tr = 1;
	}
      write_start_td_html_file(fp, v->prelim);
      /*print_tds(fp, v->prelim);*/
      if(simple)
	print_simple_node_info(fp,v);
      else
	print_node_info(fp,v,e); 

      write_end_td_html_file(fp);

      if(v->prelim == 0)
	{
	  write_end_tr_html_file(fp);
	  flag_tr = 0;
	}
    }

  for(poed = eout->next; poed != eout; poed = poed->next)
    {
      struct edge *e = (struct edge *)poed->info;
      struct pt * tv = get_to_vertex(e);

      if(e->attrib == 'z')
	continue;

      if(e->class != TREE_CLASS)
	continue;

      if( tv->mark == False)
	{
	  int p;

	  p = visit_nodes_by_DFS_table(tgf, tv, e, fp, what, level+1,simple);

	  if(!what)
	    v->prelim += p;
	    
	}
    }


  if(level > max_level)
    max_level = level;
  
  v->pick = True;

  /*printf("%d Node %s has %d leaves\n",v->level, v->label, v->prelim); */

  if(v->prelim && !what)
    return v->prelim;
  else
    return 1;
}


int
is_spaces(char * str)
{
  for(; *str != '\0'; str++)
    if(*str != ' ')
      return 0;
  return 1;
}
void
print_node_info(FILE *fp, struct pt *v, PEDGE e)
{
  const char *a1=get_attribute(v,"title");
  const char *a6=get_attribute(v,"ROOT_URL");
  char * vl = get_label_vertex(v);
  char * vw = get_weight_vertex(v);
  char *sanchor = e ? get_label_edge(e) : NULL;

  if((get_shape(v)==PENTAGON ||get_shape(v)==HEXAGON) && a6)
    {
      char *vlh = change_end_name(vl,"gr", "html");
      if(vlh)
	{
	  if(get_shape(v)==HEXAGON)
	      fprintf(fp,"<A HREF=\"%s\" TARGET=\"preview\"><IMG SRC=\"http://www.cs.rpi.edu/~puninj/images/off.gif\"></A> <I>(%s links)</I><BR><A HREF=\"%s\">%s</A>\n",
		      vlh,(vw ? vw : "error"),a6,a1);

	  else
	      fprintf(fp,"<A HREF=\"%s\"><IMG SRC=\"http://www.cs.rpi.edu/~puninj/images/off.gif\"></A> <I>(%s links)</I><BR><A HREF=\"%s\">%s</A>\n",
		      vlh,(vw ? vw : "error"),a6,a1);
	  free(vlh); vlh = NULL;
	}
      else
	fprintf(fp,"<A HREF=\"%s\">%s</A>\n", a6,a1);
    }
  else if(get_shape(v)==BOX && a1 && !is_spaces((char *)a1))
  {
      if(!strcmp(a1,"No title") && sanchor)
	  fprintf(fp,"<A HREF=\"%s\">%s<BR>%s</A>\n",vl,a1,sanchor);
      else
	  fprintf(fp,"<A HREF=\"%s\">%s</A>\n",vl,a1);
  }	  
  else if(get_shape(v)==TRIANGLE)
  {
      if(sanchor)
	  fprintf(fp,"<IMG SRC=\"http://www.cs.rpi.edu/~puninj/images/anoway.gif\"> <A HREF=\"%s\">%s<BR>%s</A>\n",vl, sanchor,vl);
      else
	  fprintf(fp,"<IMG SRC=\"http://www.cs.rpi.edu/~puninj/images/anoway.gif\"> <A HREF=\"%s\">%s</A>\n",vl,vl);
  }
  else 
  {
      if(sanchor)
	  fprintf(fp,"<A HREF=\"%s\">%s<BR>%s</A>\n",vl,sanchor,vl);
      else
	  fprintf(fp,"<A HREF=\"%s\">%s</A>\n",vl,vl);
  }
}

void
print_simple_node_info(FILE *fp, struct pt *v)
{
  const char *a1=get_attribute(v,"title");
  char * vl = get_label_vertex(v);
  
  write_string_html_file(fp,vl);
  if(a1)
    {
      write_break_html_file(fp);
      /*fprintf(fp,"<BR>");*/
      write_string_html_file(fp,(char *)a1);
    }
}


char *
change_end_name(char *s, char *e1, char *e2)
{
  int i,l=strlen(s);
  for(i=l; i>=0; i--)
    {
      if(s[i]=='.')
	break;
    }
  if(i>0 && i< l)
    {
      char *str;
      if(strcmp(&(s[i+1]), e1))
	return NULL;
      str = malloc(i+strlen(e2)+2);
      if(!str) {
	  fprintf(stderr,"Out of Memory change_end_name\n");
	  abort();
      }
      strncpy(str,s,i+1);
      str[i+1]='\0';
      strcat(str,e2);
      return str;
    }
  return NULL;
}

void 
visit_nodes_by_list(tgrFrame *tgf, struct pt *v, LNode_type *glist, 
		    FILE *fp)
{
    LNode_type *ptr = NULL;
    int clevel = 0;
    PNODE u = NULL, t = NULL;
    PEDGE e = NULL;
    for(ptr = glist->back; ptr != glist; ptr = ptr->back)
    {
	u = (PNODE)ptr->info;
	if(u && t)
	    e = find_edge_by_name(tgf->gf,t->label,u->label);
	if(u->level == clevel + 1)
	{
	    write_start_ul_html_file(fp);
	}
	else if(u->level < clevel)
	{
	    do {
		write_end_ul_html_file(fp);
		clevel--;
	    } while(u->level!=clevel);
	}
	if(u->level)
	    write_item_html_file(fp);
	print_node_info(fp,u,e);
	clevel = u->level;
	t = u;
	/*fprintf(fp, "LEVEL %d<BR>\n",u->level);*/
    }
}

void
write_body_hierarchical_tree_html_file(FILE *fp, tgrFrame *tgf, PNODE r)
{
    int list = 1;
    GraphFrame *gf = tgf->gf;
    LNode_type *hlist = NULL;
    write_start_body_html_file(fp,"#ffffff");
    write_header_html_file(fp,1,"Index");
    hlist = classify_hierarchical_edges(gf,r);
    reset_mark_pick_vertices(gf);
    if(list && hlist)
    {
	/*visit_nodes_by_DFS(tgf,r,NULL,fp,simple);*/
	visit_nodes_by_list(tgf,r,hlist, fp);
	return;
    }
    write_end_body_html_file(fp);
    if(hlist) {
      Delete_all_list(hlist);
      hlist = NULL;
  }
}

char *
title_from_ht_root(PNODE root)
{
  if(!root)
      return NULL;

  if(root)
    {
      const char *a1 = get_attribute(root,"title");
      int len = a1 ? strlen(a1):0;
      char *ti = malloc(len+ 20);
      if(!ti) {
	  fprintf(stderr,"Out of Memory title_from_ht_root\n");
	  abort();
      }
      if(a1)
	sprintf(ti, "Index of %s", a1);
      else
	sprintf(ti, "Index");
      return ti;
    }
  else
    {
      char *ti = NULL;
      GRStrAllocCopy(ti,"Index");
      return ti;
    }
  return NULL;
}

void
report_hierarchical_tree(tgrFrame *tgf, char *filename,PNODE v)
{
    FILE *fp = assert_open_text_file(filename);
    char *title=title_from_ht_root(v);
    if(!fp)
	return;
    write_head_html_file(fp,title ? title : "");
    write_body_hierarchical_tree_html_file(fp, tgf, v);

    write_end_html_file(fp);
    fclose(fp);
    if(title) free(title);
}




